﻿using System.Collections.Generic;
using System.Linq;
using SIG.Repository;
using SIG.Infrastructure.Logging;
using SIG.Infrastructure.Cache;
using SIG.Infrastructure.Configs;
using System.Linq.Expressions;
using System;
using SIG.Basic.Extensions;
using SIG.Resources.Admin;
using SIG.Model.Ads;

namespace SIG.Service
{
    public class PositionService :  EntityService<Position>, IPositionService
    {
       
        private readonly IPositionRepository _positionRepository;
        private readonly ILoggingService _loggingService;
        private readonly ICacheService _cacheService;

        public PositionService(IPositionRepository positionRepository, ILoggingService loggingService, ICacheService cacheService)
            : base(positionRepository, cacheService, loggingService)
        {           
            _positionRepository = positionRepository;
            _loggingService = loggingService;
            _cacheService = cacheService;
        }

        public Position GetPositionByCode(string code)
        {

            //get list
            var key = $"{EntityNames.Position}_{code}";

            Position position;

            if (SettingsManager.Ads.EnableCaching)
            {
                if (_cacheService.IsSet(key))
                {
                    position = (Position)_cacheService.Get(key);

                }
                else
                {
                    position = _positionRepository.GetFirstOrDefault(m => m.Active && m.Code == code);
                    _cacheService.Set(key, position, SettingsManager.Ads.CacheDuration);
                }
            }
            else
            {
                position = _positionRepository.GetFirstOrDefault(m => m.Active && m.Code == code); ;
            }

            return position;

        }

        public List<Position> GetActiveAllElements()
        {

            //get list
            var key = $"{EntityNames.Position}_Active_AllList";

            List<Position> categories;         

            if (SettingsManager.Ads.EnableCaching)
            {
                if (_cacheService.IsSet(key))
                {
                    categories = (List<Position>)_cacheService.Get(key);

                }
                else
                {
                    categories = _positionRepository.GetFilteredElements(m=>m.Active, m=>m.Carousels).ToList();
                    _cacheService.Set(key, categories, SettingsManager.Ads.CacheDuration);
                }
            }
            else
            {
                categories = _positionRepository.GetFilteredElements(m => m.Active, m => m.Carousels).ToList();
            }

            return categories;

        }

        public List<Position> GetPagedElements(int pageIndex, int pageSize, string keyword, out int totalCount)
        {

            //get list count
            var keyCount = $"{EntityNames.Position}_ListCount_{keyword}";

            var totalIQuery = _positionRepository.GetAllElements().Where(g => g.Active);
            if (!string.IsNullOrEmpty(keyword))
                totalIQuery = totalIQuery.Where(g => g.Title.Contains(keyword));
         
            if (SettingsManager.Ads.EnableCaching)
            {
                if (_cacheService.IsSet(keyCount))
                {
                    totalCount = (int)_cacheService.Get(keyCount);
                }
                else
                {
                    totalCount = totalIQuery.Count();
                    _cacheService.Set(keyCount, totalCount, SettingsManager.Ads.CacheDuration);
                }
            }
            else
            {
                totalCount = totalIQuery.Count();
            }


            //get list
            var key = $"{EntityNames.Position}_List_{pageIndex}_{pageSize}_{keyword}";

            List<Position> categories;
            Expression<Func<Position, bool>> filter = g => g.Active;
            Expression<Func<Position, bool>> filterByKeyword = g => g.Title.Contains(keyword);
       

            if (!string.IsNullOrEmpty(keyword))
                filter = filter.AndAlso(filterByKeyword);          


            if (SettingsManager.Ads.EnableCaching)
            {
                if (_cacheService.IsSet(key))
                {
                    categories = (List<Position>)_cacheService.Get(key);

                }
                else
                {
                    categories = _positionRepository.GetPagedElements(pageIndex, pageSize, (c => c.CreatedDate), filter, false).ToList();
                    _cacheService.Set(key, categories, SettingsManager.Ads.CacheDuration);
                }
            }
            else
            {
                categories = _positionRepository.GetPagedElements(pageIndex, pageSize, (c => c.CreatedDate), filter, false).ToList();
            }

            return categories;

        }

    }
}
